from fun.nodes import *

def parse(source: str, package) -> Call:
    from fun import lambda_
    syntax_stack: list[Call] = [Call(Value(lambda_), package)]
    literals = {"'": 0, '"': 0}
    s = ''
    def append():
        nonlocal s
        if not s:
            return
        end = syntax_stack[-1]
        if end.args and isinstance(end.args[-1], Value):
            last = end.args[-1].value
            if isinstance(last, Attribute) and last.attr is None:
                last.attr = s
                s = ''
                return
        end.append(get_node(s, package))
        s = ''
    for c in source:
        for k, v in literals.items():
            if v > 0:
                if c == k:
                    literals[k] = 3 - literals[k]
                    if literals[k] == 1:
                        s += c
                    break
                elif v == 1:
                    literals[k] = 0
                else:
                    s += c
                    break
        else:
            if c.isspace():
                append()
            elif c == '(':
                append()
                syntax_stack.append(syntax_stack[-1].drop())
            elif c == ')':
                append()
                syntax_stack.pop()
            elif c == '.':
                if s.isnumeric():
                    s += c
                else:
                    append()
                    syntax_stack[-1].dropattr()
            elif c == ':':
                if s:
                    append()
                syntax_stack[-1].dropkw()
            else:
                s += c
            for k in literals:
                literals[k] = 2 if c == k else 0
    if s:
        append()
    return syntax_stack[0]